﻿using System.Xml;
using System.Windows.Forms;
using SdmxMl.Common;

namespace SdmxMl.Structure
{
    /// <summary>
    /// StructureSetType describes the relationships between two or more key families and/or
    /// metadata structure definitions, including the mapping between category schemes and
    /// concept schemes, to provide for the mapping of representations. This can include
    /// inheritance and extension of properties, or total or partial equivalencies. It also
    /// includes mapping of concepts existing in metadata structure definitions to those used
    /// in key families, and vice-versa. A human-readable name is provided in the Name element,
    /// which may include several language-specific variants. A longer human-readable description
    /// may also be provided, in the Description element, which may also have language-specific
    /// variants provided. The Annotations element may be used to provide annotations.
    /// The StructureRefs element references all of the key families and/or metadata structure
    /// definitions included in the Structure Set - these must be provided if a StructureMap
    /// element is used, but is not required if the structure set is only used to provide codelist
    /// mappings, concept mappings, or category mappings. The StructureMap element indicates which
    /// components in the included data and metadata structures are equivalent; CodelistMap indicates
    /// which codes map to other codelists. CategorySchemeMap indicates which categories in one
    /// scheme map to those in another scheme. ConceptSchemeMap indicates which concepts in one
    /// scheme map to those in another scheme. OrganisationSchemeMap describes how one organisation
    /// scheme maps to another. The id attribute takes an id which is unique to all structure sets
    /// maintained by the agency specified in the agency attribute. version specifies a version
    /// number (by default "1.0"). The uri attribute holds a URL where a valid SDMX Structure
    /// messgae can be found which provides full details of the StructureSet, and it must be used
    /// if the isExternalReference attribute has a value of true. The urn attribute holds a valid
    /// SDMX Registry URN as described in the SDMX Registry specification. A true value in the
    /// isFinal attribute indicates that the contents of the structure set may not be changed
    /// without versioning. The validFrom and validTo attributes provide inclusive dates for
    /// providing supplemental validity information about the version.
    /// </summary>
    public class StructureSetType : Artefact
    {
        private MapList _maps;
        public CodelistMapType CodelistMap { get; set; }

        public override ArtefactRefTypedList ArtefactRefList
        {
            get
            {
                ArtefactRefTyped at = null;
                ArtefactRefTypedList list = new ArtefactRefTypedList();
                if (CodelistMap.MapList.SourceRef.IsFilled)
                {
                    at = new ArtefactRefTyped(CodelistMap.MapList.ArtType, CodelistMap.MapList.SourceRef.FullIdent);
                    if (list.Contains(at.Type, at.FullIdent) == false)
                        list.Add(at);
                }

                if (CodelistMap.MapList.TargetRef.IsFilled)
                {
                    at = new ArtefactRefTyped(CodelistMap.MapList.ArtType, CodelistMap.MapList.TargetRef.FullIdent);
                    if (list.Contains(at.Type, at.FullIdent) == false)
                        list.Add(at);
                }
                return list;
            }
        }

        public StructureSetType()
            : base()
        {
            Init();
            /*
            // Temp Creator
            string agency = "CH1_BUR";
            Id = "SET_UV_LINK";
            AgencyId = agency;
            Name.UpdateForLanguage("en", " transfer key");
            Name.UpdateForLanguage("de", "Umsteigeschlüssel");
            Name.UpdateForLanguage("fr", "Clés de passage");
            Name.UpdateForLanguage("it", "Chiavi di conversione");

            CodelistMap.MapList.SourceRef.AgencyId = agency;
            CodelistMap.MapList.SourceRef.Id = "CL_BUR_UNIVERS";
            CodelistMap.MapList.SourceRef.Version = "1.0";

            CodelistMap.MapList.TargetRef.AgencyId = agency;
            CodelistMap.MapList.TargetRef.Id = "CL_BUR_LINK";
            CodelistMap.MapList.TargetRef.Version= "1.0";
            CodelistMap.Id = "MAP_LINK";
            CodelistMap.Name.UpdateDefaultText("Umsteigeschlüssel");

            using (System.IO.StreamReader sr = new System.IO.StreamReader(@"O:\SI\CODAM\05_Dienst_Metastat\Activités et projets  statistiques\BUR\cdm_univers_extra.txt"))
            {
                string line = string.Empty;
                // sKIP hEADER
                line = sr.ReadLine();
                do
                {
                    line = sr.ReadLine();
                    if (line != null)
                    {
                        string[] arr = line.Split(';');
                        if (arr.Length > 2)
                        {
                            CodeMapType item = new CodeMapType();
                            item.Source = arr[0].Replace(".", "");
                            item.Target = arr[2];
                            CodelistMap.MapList.Add(item);
                        }
                    }
                } while (line != null);
            }
            */
        }

        private void Init()
        {
            CodelistMap = new CodelistMapType();
            _maps = new MapList(this);
        }

        public StructureSetType(XmlNode nodeArtefact, SdmxNamespaceManager nsmgr)
            : base(nodeArtefact, nsmgr)
        {
            Init();
            XmlNode ndCodelistMap = nodeArtefact.SelectSingleNode("structure:CodelistMap", nsmgr);
            if (ndCodelistMap != null)
                CodelistMap = new CodelistMapType(ndCodelistMap, nsmgr);
            else
                CodelistMap = new CodelistMapType();

       }

        public override TreeNode FillNode(TreeNode parentNode)
        {
            TreeNode t = base.FillNode(parentNode);
            TreeNode nd = new TreeNode();
            nd.Text = _maps.ToString();
            nd.Tag = _maps;
            t.Nodes.Add(nd);

            return t;
        }


        public override void WriteXmlInsider(XmlTextWriter xw)
        {
            string prefix = "structure";
            CodelistMap.WriteXml(xw, prefix, "CodelistMap");
        }

        #region Artefact Type

        public override Manager.SdmxArtefactType ArType
        {
            get { return Manager.SdmxArtefactType.StructureSets; }
        }

        #endregion

    }

    public class MapList
    {
        public StructureSetType Maps { get; set; }

        public MapList(StructureSetType st)
        {
            Maps = st;
        }

        public override string ToString()
        {
            return "Maps";
        }
    }

}
